package models.venue.policy;

import jodd.bean.BeanCopy;
import models.BaseModel;
import models.constants.DeletedStatus;
import models.merchant.Merchant;
import models.venue.coach.Coach;
import models.venue.enums.PolicyType;
import models.venue.fitness.Fitnesses;
import models.venue.room.Room;
import play.Logger;
import play.modules.paginate.JPAExtPaginator;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 场地价格策略
 * Created by hanbin on 17/4/5.
 */
@Entity
@Table(name="policies")
public class Policy  extends BaseModel {

//    /**
//     * 生效开始日期
//     */
//    @Column(name="start_date", length = 50)
//    public Date startDate;
//
//    /**
//     * 生效结束日期
//     */
//    @Column(name="end_date", length = 50)
//    public Date endDate;

    /**
     * 所属店面
     */
    @JoinColumn(name="merchant_id")
    @ManyToOne
    public Merchant merchant;

    /**
     * 健身类型
     */
    @JoinColumn(name="fitnesses_id")
    @ManyToOne
    public Fitnesses fitnesses;

    /**
     * 包房
     */
    @JoinColumn(name="room_id")
    @ManyToOne
    public Room room;

    /**
     * 开始时间
     */
    @Column(name="start_time", length = 50)
    public String startTime;

    /**
     * 结束时间
     */
    @Column(name="end_time", length = 50)
    public String endTime;

    /**
     * 价格
     */
    @Column(name = "price")
    public BigDecimal price;

    /**
     * 微信价格
     */
    @Column(name = "wechat_price")
    public BigDecimal wechatPrice;

    /**
     * 顺序号
     */
    @Column(name = "sequence")
    public Integer sequence;

    /**
     * 价格策略类型
     */
    @Column(name = "policy_type")
    @Enumerated(EnumType.STRING)
    public PolicyType policyType;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;


    /**
     * Update
     * @param id
     * @param newObject
     */
    public static void update(Long id, Policy newObject) {
        Policy policy = Policy.findById(id);
        BeanCopy.beans(newObject, policy).ignoreNulls(true).copy();
        policy.save();
    }


    /**
     * 加载价格策略   价格策略分为两个优先级
     * 遇到其他加载不上的情况  需要重新修正和认定
     * @param coach
     * @param beginTime
     * @param endTime
     * @return
     */
    public static Policy findByCoachAndBeginTimeAndEndTime(Coach coach , String beginTime , String endTime) {
//        Logger.info("findByCoachAndBeginTimeAndEndTime  fitnessId : %s , startTime : %s , endTme : %s" , coach.fitnesses.id , beginTime , endTime);
        Policy policy =  Policy.find("fitnesses.id = ? and startTime <= ? and endTime >= ? and deleted = ? order by sequence desc" , coach.fitnesses.id , beginTime , endTime , DeletedStatus.UN_DELETED).first();
//        if(policy == null) {
//            policy =  Policy.find("fitnesses.id = ? and ? >= endTime and deleted = ? order by sequence desc" , coach.fitnesses.id , beginTime , DeletedStatus.UN_DELETED).first();
//        }

        if(policy == null) {
            policy =  Policy.find("fitnesses.id = ? and ? <= endTime and ? >= endTime and  deleted = ? order by sequence desc" , coach.fitnesses.id , beginTime , endTime , DeletedStatus.UN_DELETED).first();
        }

        return policy;
    }

    /**
     * 加载价格策略   价格策略分为两个优先级
     * 遇到其他加载不上的情况  需要重新修正和认定
     * @param room
     * @param beginTime
     * @param endTime
     * @return
     */
    public static Policy findByRoomAndBeginTimeAndEndTime(Room room , String beginTime , String endTime) {
        Policy policy =  Policy.find("room.id = ? and startTime <= ? and endTime >= ? and deleted = ? order by sequence desc" , room.id , beginTime , endTime , DeletedStatus.UN_DELETED).first();
        if(policy == null) {
            policy =  Policy.find("room.id = ? and ? <= endTime and ? >= endTime and  deleted = ? order by sequence desc" , room.id , beginTime , endTime , DeletedStatus.UN_DELETED).first();
        }
        return policy;
    }


    /**
     * 分页查询.
     */
    public static JPAExtPaginator<Policy> findByCondition(Map<String, Object> conditionMap, String orderByExpress, int pageNumber, int pageSize) {
        StringBuilder xsqlBuilder = new StringBuilder("t.deleted=models.constants.DeletedStatus.UN_DELETED ")
                .append("/~ and t.fitnesses.id = {fitnessId} ~/")
                .append("/~ and t.room.roomName like {roomName} ~/")
                .append("/~ and t.policyType = {policyType} ~/")
                .append("/~ and t.merchant.id = {merchantId} ~/");

        util.xsql.XsqlBuilder.XsqlFilterResult result = new util.xsql.XsqlBuilder().generateHql(xsqlBuilder.toString(), conditionMap);
        JPAExtPaginator<Policy> resultPage = new JPAExtPaginator<>("Policy t", "t", Policy.class,
                result.getXsql(), conditionMap).orderBy(orderByExpress);
        resultPage.setPageNumber(pageNumber);
        resultPage.setPageSize(pageSize);
        resultPage.setBoundaryControlsEnabled(false);
        return resultPage;
    }

    public static List<Policy> findRoomPolicyForOffline(Room room , String beginTime , String endTime) {
        return Policy.find("room.id = ? and endTime >= ? and startTime <= ? and deleted = ? order by sequence desc" , room.id , beginTime , endTime , DeletedStatus.UN_DELETED).fetch();
    }

    public static Policy findByRoomAndStartAndEnd(Room room , String beginTime , String endTime) {
        return Policy.find("room.id = ? and endTime >= ? and startTime <= ? and deleted = ? order by sequence desc" , room.id , beginTime , endTime , DeletedStatus.UN_DELETED).first();
    }

}
